Skip to content

Conversation

ssf-ford
Copy link

Casting f"0.self.get_time('EXIF:SubSecTime')" directly causes ValueError as the string to be casted is in the format '0.-nnnnnn'.

Santawat Santiteerakul added 2 commits March 22, 2025 19:56
Casting f"0.self.get_time('EXIF:SubSecTime')" directly causes ValueError
as the string to be casted is in the format '0.-nnnnnn'
@maurerle
Copy link

maurerle commented Jul 8, 2025

Hi, when did this occur with which camera?
With our MicaSense RedEdge-P this is working fine.

How are you processing the images?

@ssf-ford
Copy link
Author

Hi,

when did this occur with which camera?

I encountered this issue in March 2025, however, the image set is quite old from RedEdge-M (the red body) camera taken in 2018. I've also included the set in my unit test commit

Note: This commit eeaf6e8 introduced the type casting f"0.self.get_time('EXIF:SubSecTime')".

How are you processing the images?

  • I cloned the repository and use the micasense code as a python module
  • I use Python 3.10.15 installed via pyenv
  • Here's the code snippet that I ran.
import micasense.capture as capture
import micasense.imageutils as imageutils


def get_image_type_and_irradiance(the_capture, panel_cap):
    """
    Determine if the output image should be "reflectance" or "radiance"
    and compute the irradiance list using panel capture if available.
    """
    if panel_cap is not None:
        if panel_cap.panel_albedo() is not None:
            panel_reflectance_by_band = panel_cap.panel_albedo()
        else:
            panel_reflectance_by_band = [0.49] * len(
                the_capture.eo_band_names()
            )  # RedEdge band_index order
        irradiance_list = panel_cap.panel_irradiance(panel_reflectance_by_band) + [0]
        # prevent negative irradiance
        irradiance_list = np.abs(irradiance_list).tolist()
        the_capture.plot_undistorted_reflectance(irradiance_list)
        return "reflectance", irradiance_list
    else:
        if the_capture.dls_present():
            irradiance_list = the_capture.dls_irradiance() + [0]
            # prevent negative irradiance
            irradiance_list = np.abs(irradiance_list).tolist()
            the_capture.plot_undistorted_reflectance(irradiance_list)
            return "reflectance", irradiance_list
        else:
            the_capture.plot_undistorted_radiance()
            return "radiance", None

def align_non_panchro_capture(
    the_capture,
    warp_matrices,
    img_type,
    match_index,
    pyramid_levels,
    max_alignment_iterations,
    warp_mode,
    regenerate=True,
    multithreaded=False,
):
    """
    For non-panchromatic cameras, align the capture using OpenCV.
    """
    st = time.time()
    # Set regenerate flag to force creation of new warp matrices (or use already loaded ones)
    if warp_matrices and not regenerate:
        print("Using existing warp matrices...")
    else:
        print("Aligning images...")
        warp_matrices, alignment_pairs = imageutils.align_capture(
            the_capture,
            ref_index=match_index,
            max_iterations=max_alignment_iterations,
            warp_mode=warp_mode,
            pyramid_levels=pyramid_levels,
            multithreaded=multithreaded,
        )

    print("Finished aligning")
    et = time.time()
    print("Alignment time:", int(et - st), "seconds")

    cropped_dimensions, edges = imageutils.find_crop_bounds(
        the_capture, warp_matrices, warp_mode=warp_mode, reference_band=match_index
    )
    print("Cropped dimensions:", cropped_dimensions)

    im_aligned = the_capture.create_aligned_capture(
        warp_matrices=warp_matrices, motion_type=warp_mode, img_type=img_type
    )
    return im_aligned, warp_matrices


main():
    image_names = [
        '/path/to/IMG_0008_1.tif',
        '/path/to/IMG_0008_2.tif',
        '/path/to/IMG_0008_3.tif',
        '/path/to/IMG_0008_4.tif',
        '/path/to/IMG_0008_5.tif'
    ]
    warp_matrices = None
    regenerate = True
    sharpened_stack = None
    warp_mode = cv2.MOTION_HOMOGRAPHY
    max_alignment_iterations = 10
    multithreaded = True

    the_capture = capture.Capture.from_filelist(image_names)
    img_type, irradiance_list = get_image_type_and_irradiance(the_capture, None)
    im_aligned, warp_matrices = align_non_panchro_capture(
          the_capture,
          warp_matrices,
          img_type,
          match_index,
          pyramid_levels,
          max_alignment_iterations,
          warp_mode,
          regenerate=regenerate,
          multithreaded=multithreaded
   )

...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants